package com.groupware.gw.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.groupware.gw.model.GWModel;
import com.groupware.gw.service.GWService;
import com.groupware.member.model.MemberModel;

@Controller
@RequestMapping("/gw")
public class GWController {
	// DI
	private ApplicationContext context = new ClassPathXmlApplicationContext("/config/applicationContext.xml");
	private GWService gwService = (GWService) context.getBean("gwService");
	//
	// file upload path
	private String uploadPath = "C:\\dev\\workspace\\sts\\Groupware-Project\\src\\main\\webapp\\files\\";
	//
	//
	
	@RequestMapping("/list.do")
	public ModelAndView gwList(HttpServletRequest request, HttpServletResponse response,  HttpSession session){
		String userId = (String)session.getAttribute("userId");
		List<GWModel> gwList = gwService.getGWList(userId);
		
		ModelAndView mav = new ModelAndView();
		mav.addObject("gwList", gwList);
		mav.setViewName("/gw/list");
		return mav;
	}
	
	@RequestMapping("/approveList.do")
	public ModelAndView gwApproveList(HttpServletRequest request, HttpServletResponse response,  HttpSession session){
		String userId = (String)session.getAttribute("userId");
		List<GWModel> gwApproveList = gwService.getGWApproveList(userId);
		
		ModelAndView mav = new ModelAndView();
		mav.addObject("gwApproveList", gwApproveList);
		mav.setViewName("/gw/approveList");
		return mav;
	}
	
	@RequestMapping("/view.do")
	public ModelAndView gwView(HttpServletRequest request, HttpSession session) throws UnknownHostException{
		int document_no = Integer.parseInt(request.getParameter("document_no"));
		String loginId = (String) session.getAttribute("userId");
		
		GWModel gwBoard = gwService.getOneGWArticle(document_no);
		
		ModelAndView mav = new ModelAndView();
		MemberModel approval1 = null;
		MemberModel approval2 = null;
		MemberModel approval3 = null;
		int step = gwBoard.getDocumentTotalStep();
		
		if(step >= 1){
			approval1 = gwService.getOneUserName(gwBoard.getApproval1());
			mav.addObject("approval1", approval1);
		}
		if(step >= 2){
			approval2 = gwService.getOneUserName(gwBoard.getApproval2());
			mav.addObject("approval2", approval2);
		}
		if(step >= 3){
			approval3 = gwService.getOneUserName(gwBoard.getApproval3());
			mav.addObject("approval3", approval3);
		}
		
		mav.addObject("gwBoard", gwBoard);
		mav.addObject("loginId", loginId);
		mav.addObject("step", gwBoard.getDocumentStep());
		mav.setViewName("/gw/view");
		return mav;
	}
	
	@RequestMapping("/approveView.do")
	public ModelAndView gwApproveView(HttpServletRequest request, HttpSession session) throws UnknownHostException{
		int document_no = Integer.parseInt(request.getParameter("document_no"));
		String loginId = (String) session.getAttribute("userId");
		
		GWModel gwBoard = gwService.getOneGWArticle(document_no);
		
		ModelAndView mav = new ModelAndView();
		MemberModel approval1 = null;
		MemberModel approval2 = null;
		MemberModel approval3 = null;
		int step = gwBoard.getDocumentTotalStep();
		
		if(step >= 1){
			approval1 = gwService.getOneUserName(gwBoard.getApproval1());
			mav.addObject("approval1", approval1);
		}
		if(step >= 2){
			approval2 = gwService.getOneUserName(gwBoard.getApproval2());
			mav.addObject("approval2", approval2);
		}
		if(step >= 3){
			approval3 = gwService.getOneUserName(gwBoard.getApproval3());
			mav.addObject("approval3", approval3);
		}
		
		mav.addObject("gwBoard", gwBoard);
		mav.addObject("loginId", loginId);
		mav.addObject("step", step);
		mav.setViewName("/gw/approveView");
		return mav;
	}
	
	
	@RequestMapping("/write.do")
	public ModelAndView gwWrite(@ModelAttribute("GWModel") GWModel gwModel, HttpSession session){
		String userId = (String)session.getAttribute("userId");
		List<MemberModel> userList = gwService.getUserName(userId);
		
		ModelAndView mav = new ModelAndView();
		mav.addObject("userList", userList);
		mav.setViewName("/gw/write");
		return mav;
	}
	
	@RequestMapping(value="/write.do", method=RequestMethod.POST)
	public String gwWriteProc(@ModelAttribute("GWModel") GWModel gwModel, MultipartHttpServletRequest request){
		
		// get upload file
		MultipartFile file = request.getFile("file");
		String fileName = "";
		if(file.getSize() > 0){
			fileName = file.getOriginalFilename();
			File uploadFile = new File(uploadPath + fileName);
			// when file exists as same name
			if(uploadFile.exists()){
				fileName = new Date().getTime() + fileName;
				uploadFile = new File(uploadPath + fileName);
			}
			// save upload file to uploadPath
			try {
				file.transferTo(uploadFile);
			} catch (Exception e) {
			}
		}
		//
		// new line code change to <br /> tag
		String subject =  gwModel.getSubject().replaceAll("\r\n", "<br />");		
		//
		gwModel.setFiles(fileName);
		gwModel.setSubject(subject);
		
		if(gwModel.getApproval3().isEmpty()){
			gwModel.setDocumentTotalStep(2);
			if(gwModel.getApproval2().isEmpty()){
				gwModel.setDocumentTotalStep(1);
				if(gwModel.getApproval1().isEmpty()){
					gwModel.setDocumentTotalStep(0);
				}
			}
		}else{
			gwModel.setDocumentTotalStep(3);
		}
		//
		gwService.writeGWArticle(gwModel);
		
		return "redirect:list.do";
	}
	
	@RequestMapping(value="/approve.do", method=RequestMethod.GET)
	public String approve(HttpServletRequest request, HttpSession session){
		//입력 
		int step = Integer.parseInt(request.getParameter("num"));
		String approveDate = "approveDate" + step;
		int document_no = Integer.parseInt(request.getParameter("document_no"));
		GWModel gwBoard = gwService.getOneGWArticle(document_no);
		
		step += 1;
		
		gwService.updateApprove(document_no, approveDate, step);
		return "redirect:view.do?document_no="+document_no;
	}
	
	@RequestMapping("/modify.do")
	public ModelAndView gwModify(HttpServletRequest request, HttpSession session){
		String userId = (String) session.getAttribute("userId");
		int document_no = Integer.parseInt(request.getParameter("document_no"));
		
		GWModel board = gwService.getOneGWArticle(document_no);
		
		// <br /> tag change to new line code
		String content = board.getSubject().replaceAll("<br />", "\r\n");
		board.setSubject(content);
		List<MemberModel> userList = gwService.getUserName(userId);
		
		ModelAndView mav = new ModelAndView();
		
		if(!userId.equals(board.getUserId())){
			mav.addObject("errCode", "1");	// forbidden connection
			mav.addObject("document_no", document_no);
			mav.setViewName("redirect:view.do");
		} else {
			mav.addObject("board", board);
			mav.addObject("userList", userList);
			mav.setViewName("/gw/modify");
		}
		
		return mav;
	}
	
	@RequestMapping(value = "/modify.do", method=RequestMethod.POST)
	public ModelAndView boardModifyProc(@ModelAttribute("GWModel") GWModel gwModel, MultipartHttpServletRequest request) throws UnknownHostException{
		String orgFileName = request.getParameter("orgFile");
		MultipartFile newFile = request.getFile("newFile");
		String newFileName = newFile.getOriginalFilename();
		gwModel.setFiles(orgFileName);
		
		// if: when want to change upload file
		if(newFile != null && !newFileName.equals("")){
			if(orgFileName != null || !orgFileName.equals("")){
				// remove uploaded file
				File removeFile = new File(uploadPath  + orgFileName);
				removeFile.delete();
				//
			}
			// create new upload file
			File newUploadFile = new File(uploadPath +newFileName);
			try {
				newFile.transferTo(newUploadFile);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//
			gwModel.setFiles(newFileName);
		}
		//
		// new line code change to <br /> tag
		String content =  gwModel.getSubject().replaceAll("\r\n", "<br />");		
		gwModel.setSubject(content);
		
		if(gwModel.getApproval3().isEmpty()){
			gwModel.setDocumentTotalStep(2);
			if(gwModel.getApproval2().isEmpty()){
				gwModel.setDocumentTotalStep(1);
				if(gwModel.getApproval1().isEmpty()){
					gwModel.setDocumentTotalStep(0);
				}
			}
		}else{
			gwModel.setDocumentTotalStep(3);
		}
		
		gwService.modifyGWArticle(gwModel);
		
		ModelAndView mav = new ModelAndView();
		mav.addObject("document_no", gwModel.getDocument_no());
		mav.setViewName("redirect:/gw/view.do");
		return mav;
	}
	
	@RequestMapping("/delete.do")
	public ModelAndView gwDelete(HttpServletRequest request, HttpSession session){
		String userId = (String) session.getAttribute("userId");
		int document_no = Integer.parseInt(request.getParameter("document_no"));
		
		GWModel gw = gwService.getOneGWArticle(document_no);
		
		ModelAndView mav = new ModelAndView();
		
		if(!userId.equals(gw.getUserId())){
			mav.addObject("errCode", "1");	// it's forbidden connection
			mav.addObject("document_no", document_no);
			mav.setViewName("redirect:view.do");
		} else {
			// if: when the article has upload file - remove that
			if(gw.getFiles() != null){
				File removeFile = new File(uploadPath + gw.getFiles());
				removeFile.delete();
			}
			//				
			gwService.deleteArticle(document_no);
			
			mav.setViewName("redirect:list.do");
		}		
		return mav;
	}
	
	
	
	@RequestMapping("/fileDownload.do")
	public void fileDownload(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		// 파일 이름이 파라미터로 넘어오지 않으면 리다이렉트 시킨다.
		if (request.getParameter("fileName") == null
				|| "".equals(request.getParameter("fileName"))) {

			PrintWriter out = response.getWriter();
			out.print("<script>alert('error'); self.close();</script>");

		} else {

			// 파라미터로 받은 파일 이름.
			String requestFileNameAndPath = uploadPath + File.separator
					+ request.getParameter("fileName");

			// 서버에서 파일찾기 위해 필요한 파일이름(경로를 포함하고 있음)
			// 한글 이름의 파일도 찾을 수 있도록 하기 위해서 문자셋 지정해서 한글로 바꾼다.
			String UTF8FileNameAndPath = new String(
					requestFileNameAndPath.getBytes("8859_1"), "UTF-8");

			// 파일이름에서 path는 잘라내고 파일명만 추출한다.
			String UTF8FileName = UTF8FileNameAndPath.substring(
					UTF8FileNameAndPath.lastIndexOf("/") + 1).substring(
					UTF8FileNameAndPath.lastIndexOf(File.separator) + 1);

			// 브라우저가 IE인지 확인할 플래그.
			boolean MSIE = request.getHeader("user-agent").indexOf("MSIE") != -1;

			// 파일 다운로드 시 받을 때 저장될 파일명
			String fileNameToSave = "";

			// IE,FF 각각 다르게 파일이름을 적용해서 구분해주어야 한다.
			if (MSIE) {
				// 브라우저가 IE일 경우 저장될 파일 이름
				// 공백이 '+'로 인코딩된것을 다시 공백으로 바꿔준다.
				fileNameToSave = URLEncoder.encode(UTF8FileName, "UTF8")
						.replaceAll("\\+", " ");
			} else {
				// 브라우저가 IE가 아닐 경우 저장될 파일 이름
				fileNameToSave = new String(UTF8FileName.getBytes("UTF-8"),
						"8859_1");
			}

			// 다운로드 알림창이 뜨도록 하기 위해서 컨텐트 타입을 8비트 바이너리로 설정한다.
			response.setContentType("application/octet-stream");

			// 저장될 파일 이름을 설정한다.
			response.setHeader("Content-Disposition", "attachment; filename=\""
					+ fileNameToSave + "\";");
			// 파일패스 및 파일명을 지정한다.
			// String filePathAndName =
			// pageContext.getServletContext().getRealPath("/") +
			// UTF8FileNameAndPath;
			String filePathAndName = UTF8FileNameAndPath;
			File file = new File(filePathAndName);
			// 버퍼 크기 설정
			byte bytestream[] = new byte[2048000];
			// response out에 파일 내용을 출력한다.
			if (file.isFile() && file.length() > 0) {
				FileInputStream fis = new FileInputStream(file);
				BufferedInputStream bis = new BufferedInputStream(fis);
				BufferedOutputStream bos = new BufferedOutputStream(
						response.getOutputStream());
				int read = 0;
				while ((read = bis.read(bytestream)) != -1) {
					bos.write(bytestream, 0, read);
				}
				bos.close();
				bis.close();
			}
		}
	}
	
}